package models

import (
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego/orm"
	"github.com/funlake/gopkg/utils/log"
	"pq/helper"
)

type PqCsTestItem struct {
	Id int
	Pid int
	Type int
	Body string
	Analysis string
	AnswerDisplayType string
	Score int
	PqCsTestLibraryId int
	PqTestPointCategoryId int
	Ordering int
	State int
	AnswerData string
	TabCategoryId int
	PqCsTestResourceId int
	PqCsTestResourceBody  string
	DupEnabled int
	BaseModel
}

func (pcti *PqCsTestItem) ListAll(q ...interface{}) ([]orm.Params,interface{}){
	var nodes []orm.Params
	model := GetSlaveDb()

	_, _ = model.Raw(`
		select SQL_CALC_FOUND_ROWS ti.*,tl.title as library_title,pc.title pc_title,pc.path cate_path from pq_cs_test_item as ti
		inner join pq_cs_test_library as tl on tl.id = ti.pq_cs_test_library_id
		inner join pq_test_point_category as pc on pc.id = ti.pq_test_point_category_id
		where ti.state > ? and ti.pq_cs_test_library_id = ?
		limit ?,?
	`, q).Values(&nodes)

	var maps []orm.Params
	_, _ = model.Raw(`select count('ti.*') as amount from pq_cs_test_item as ti
		inner join pq_cs_test_library as tl on tl.id = ti.pq_cs_test_library_id
		inner join pq_test_point_category as pc on pc.id = ti.pq_test_point_category_id
		where ti.state > ?`, q[0]).Values(&maps)
	amount := maps[0]["amount"]
	return nodes,amount
}


//涵盖每种题型,15道
func (pcti PqCsTestItem) ListRandom(user PqUser,random interface{})([]orm.Params){
	var nodes []orm.Params
	model := GetSlaveDb()
	var testCategory PqTestCategory
	_ = model.QueryTable(`pq_test_category`).Filter("id", user.PqTestCategoryId).One(&testCategory)
	//		select SQL_CALC_FOUND_ROWS ti.*,tl.title as library_title,pc.title pc_title,pc.path cate_path,pr.body as resource_title from pq_cs_test_item as ti
	//		inner join pq_cs_test_library as tl on tl.id = ti.pq_cs_test_library_id
	//		inner join pq_test_category ptc on ptc.id = tl.pq_test_category_id
	//		inner join pq_test_point_category as pc on pc.id = ti.pq_test_point_category_id
	//		left join pq_cs_test_resource as pr on pr.id = ti.pq_cs_test_resource_id
	//		where ti.state > -1 and  ptc.lft >= ? and ptc.rgt <= ?
	//		order by pc.ordering desc
	//		limit ?

	// todo ,按照不同的area_code做特殊处理
	// 1. 国考则为空
	// 2. 省考，则获取省份area_code
	// 3. 其它，直接取area_code
	areaCode := user.AreaCode
	log.Info("%#v",testCategory)
	if testCategory.Code == "GK" {
		areaCode = ""
	}
	// 省考则找到省级code，并找到相应的真题
	if testCategory.Code == "SK" {
		var area Area
		_ = model.QueryTable(`area`).Filter("area_code", areaCode).One(&area)
		areaCode = area.ParentCode
	}
	_, _ = model.Raw(`
		select SQL_CALC_FOUND_ROWS ti.*,tl.title as library_title,pc.title pc_title,pc.path cate_path from pq_cs_test_item as ti
		inner join pq_cs_test_library as tl on tl.id = ti.pq_cs_test_library_id
		inner join pq_test_category ptc on ptc.id = tl.pq_test_category_id
		inner join pq_test_point_category as pc on pc.id = ti.pq_test_point_category_id
		where ti.state > 0 and tl.state > 0 and  ptc.lft >= ? and ptc.rgt <= ? and ti.pq_cs_test_resource_id = 0
		and tl.area_code = ? and ti.dup_enabled=1
		order by rand()
		limit ?
	`,testCategory.Lft, testCategory.Rgt,areaCode, random).Values(&nodes)
	return nodes
}
//专题
func (pcti PqCsTestItem) ListRandomZx(user PqUser ,point_category_id int,amount int)([]orm.Params){
	var pointCategory PqTestPointCategory
	slave := GetSlaveDb()
	_ = slave.QueryTable("pq_test_point_category").Filter("id", point_category_id).One(&pointCategory)
	var testCategory PqTestCategory
	_ = slave.QueryTable(`pq_test_category`).Filter("id", user.PqTestCategoryId).One(&testCategory)
	var nodes []orm.Params

	areaCode := user.AreaCode
	if testCategory.Code == "GK" {
		areaCode = ""
	}
	// 省考则找到省级code，并找到相应的真题
	if testCategory.Code == "SK" {
		var area Area
		_ = slave.QueryTable(`area`).Filter("area_code", areaCode).One(&area)
		areaCode = area.ParentCode
	}

	_, _ = slave.Raw(`
		select SQL_CALC_FOUND_ROWS ti.*,tl.title as library_title,pc.title pc_title,pc.path cate_path,pr.body as resource_title from pq_cs_test_item as ti
		inner join pq_cs_test_library as tl on tl.id = ti.pq_cs_test_library_id
		inner join pq_test_category ptc on ptc.id = tl.pq_test_category_id
		inner join pq_test_point_category as pc on pc.id = ti.pq_test_point_category_id
		left join pq_cs_test_resource as pr on pr.id = ti.pq_cs_test_resource_id
		where ti.state > 0 and tl.state >  0 and pc.lft >= ? and pc.rgt <= ? and  ptc.lft >= ? and ptc.rgt <= ?
		and tl.area_code = ? and ti.dup_enabled=1
		order by rand()
		limit ?
	`, pointCategory.Lft, pointCategory.Rgt, testCategory.Lft, testCategory.Rgt,areaCode, amount).Values(&nodes)
	return nodes
}
// problem: 接口慢
func (pcti PqCsTestItem) ListRandomCom(user PqUser) [][]orm.Params {
	slave := GetSlaveDb()
	var testCategory PqTestCategory
	_ = slave.QueryTable(`pq_test_category`).Filter("id", user.PqTestCategoryId).One(&testCategory)
	var points = testCategory.PointSetting
	var pointCategory PqTestPointCategory
	var nodes [][]orm.Params
	var node []orm.Params
	areaCode := user.AreaCode
	if testCategory.Code == "GK" {
		areaCode = ""
	}
	// 省考则找到省级code，并找到相应的真题
	if testCategory.Code == "SK" {
		var area Area
		_ = slave.QueryTable(`area`).Filter("area_code", areaCode).One(&area)
		areaCode = area.ParentCode
	}
	for _,pjson := range helper.UnmarshalPointSettingJson(points) {

		for pi, pl := range pjson {
			slave := GetSlaveDb()
			_ = slave.QueryTable("pq_test_point_category").Filter("id", pi).One(&pointCategory)
			_, _ = slave.Raw(`
		select SQL_CALC_FOUND_ROWS ti.*,pc.title pc_title,pc.path cate_path,pr.body as resource_title from pq_cs_test_item as ti
		inner join pq_cs_test_library tl on tl.id = ti.pq_cs_test_library_id
		inner join pq_test_category ptc on ptc.id = tl.pq_test_category_id
		inner join pq_test_point_category as pc on pc.id = ti.pq_test_point_category_id
		left join pq_cs_test_resource as pr on pr.id = ti.pq_cs_test_resource_id
		where ti.state > 0 and tl.state > 0 and pc.lft >= ? and pc.rgt <= ? and ptc.lft >= ? and ptc.rgt <= ?
		and tl.area_code = ? and ti.dup_enabled=1 and ti.pq_cs_test_resource_id <= 0
		order by rand()
		limit ?
		`, pointCategory.Lft, pointCategory.Rgt, testCategory.Lft, testCategory.Rgt, areaCode,pl).Values(&node)
			nodes = append(nodes, node)
		}
	}

	var library PqCsTestLibrary
	//15道资料题,随机拿一道真题 , 取出所有资料题目 , 拼接上去
	slave.Raw(`select id from pq_cs_test_library where area_code=? and state>0 order by rand() limit 1`,areaCode).QueryRow(&library)
	var resourceNode []orm.Params
	_, _ = slave.Raw(`
		select SQL_CALC_FOUND_ROWS ti.*,pc.title pc_title,pc.path cate_path,pr.body as resource_title from pq_cs_test_item as ti
		inner join pq_cs_test_library tl on tl.id = ti.pq_cs_test_library_id
		inner join pq_test_category ptc on ptc.id = tl.pq_test_category_id
		inner join pq_test_point_category as pc on pc.id = ti.pq_test_point_category_id
		left join pq_cs_test_resource as pr on pr.id = ti.pq_cs_test_resource_id
		where ti.state > 0 and tl.state > 0
		and tl.area_code = ? and tl.id=? and ti.pq_cs_test_resource_id > 0
		and ti.ordering > 85 and ti.ordering <= 100
		order by ti.ordering asc
		limit 15
		`,areaCode,library.Id).Values(&resourceNode)
	// todo : 从真题随机获取一道真题的15道题，并入以上结果
	nodes = append(nodes , resourceNode)
	log.Success(fmt.Sprintf("====%d====",len(nodes)))
	return nodes
}

func (pcti PqCsTestItem) ListSimuItems(simu_library_id string) ([]orm.Params){
	var nodes []orm.Params
	model := GetSlaveDb()
	_, _ = model.Raw(`
	select ti.*,tl.body,tl.answer_data,tl.score,tl.pq_test_point_category_id,tl.analysis,tl.pq_cs_test_library_id,tl.pq_test_point_category_id,
    pc.title as point_title,pc.path as section,tl.pq_cs_test_resource_id,tl.type from pq_cs_simu_item_connection as ti
	inner join pq_cs_test_item as tl on tl.id = ti.pq_cs_test_item_id
	inner join pq_test_point_category pc on pc.id=tl.pq_test_point_category_id
	where ti.pq_cs_test_simu_library_id = ? order by ti.ordering asc limit ?
	`, simu_library_id, 200).Values(&nodes)
	return nodes
}
func (pcti PqCsTestItem) ListSimuResource(id interface{})([]orm.Params){
	var nodes []orm.Params
	model := GetSlaveDb()
	_, _ = model.Raw(`
		select SQL_CALC_FOUND_ROWS ti.* from pq_cs_test_resource as ti
		where ti.pq_cs_test_library_id = ? order by id asc
	`, id).Values(&nodes)
	return nodes
}
func (pcti PqCsTestItem) GetOne(id interface{}) interface{}{
	var nodes []orm.Params
	model := GetSlaveDb()
	_, _ = model.Raw(`
		select SQL_CALC_FOUND_ROWS ti.*,tl.title as library_title,pc.title pc_title,pc.path cate_path from pq_cs_test_item as ti
		inner join pq_cs_test_library as tl on tl.id = ti.pq_cs_test_library_id
		inner join pq_test_point_category as pc on pc.id = ti.pq_test_point_category_id
		where ti.id = ?
	`, id).Values(&nodes)
	if len(nodes) > 0 {
		return nodes[0]
	}
	return nil
}
func (pcti PqCsTestItem) SaveAnwsers(id interface{}){
	slave := GetSlaveDb()
	master := GetMasterDb()
	var item PqCsTestItem
	_ = slave.QueryTable("pq_cs_test_item").Filter("id", id).One(&item)
	var anwsers []orm.Params
	_, _ = slave.QueryTable("pq_test_item_answer").Filter("pq_cs_test_item_id", id).Filter("state__gt", -1).Values(&anwsers)
	//todo: strip html in anwsers
	for k,_ := range anwsers{
		// anwsers[k]["Body"] = striphtmltags.StripTags(anwsers[k]["Body"].(string))
		log.Info(AnswerXssPolicy.Sanitize(anwsers[k]["Body"].(string)))
		anwsers[k]["Body"] = AnswerXssPolicy.Sanitize(anwsers[k]["Body"].(string))
	}
	storeJson,_ := json.Marshal(&anwsers)
	//beego.Warning(id)
	//beego.Warning(string(storeJson))
	_, _ = master.QueryTable("pq_cs_test_item").Filter("id", id).Update(orm.Params{
		"answer_data": string(storeJson),
	})
	//beego.Error(err)
}

func (pcti PqCsTestItem) SaveSimuAnwsers(id interface{},answer []string) bool{
	slave := GetSlaveDb()
	master := GetMasterDb()
	var item PqCsSimuItemConnection
	_ = slave.QueryTable("pq_cs_simu_item_connection").Filter("id", id).One(&item)
	ia := map[string]bool{}
	for _,item := range answer{
		ia[item] = true
	}
	storeJson,_ := json.Marshal(&ia)
	_,err := master.QueryTable("pq_cs_simu_item_connection").Filter("id",id).Update(orm.Params{
		"answer_choose_data" : string(storeJson),
	})
	return err == nil
}

